﻿/*
 * Author:  hammercui
 * CreateTime: 2018/9/30 13:42:44
 * Module:
 * 主要功能：
 *
 */

using System;
using System.Collections.Generic;
using UnityEngine;

namespace MGFramework
{
    public enum LogThread
    {
        Main,
        Other
    }

    public class ConsoleMessage
    {
        private readonly string message;
        private readonly string stackTrace;
        private readonly LogType type;
        private readonly LogThread thread;
        public string Message
        {
            get { return message; }
        }

        public string StackTrace
        {
            get { return stackTrace; }
        }

        public LogType Type
        {
            get { return type; }
        }

        public LogThread Thread
        {
            get { return thread; }
        }

        public ConsoleMessage(string message, string stackTrace, LogType type,LogThread thread)
        {
            this.message = message;
            this.stackTrace = stackTrace;
            this.type = type;
            this.thread = thread;
        }
    }

    /// <summary>
    /// 控制台gui输出类
    /// 包括FPS，内存使用情况，日志GUI输出
    /// </summary>
    public class MGConsole : UnitySingleton<MGConsole>
    {
        public static float Ping = 0;

        /// <summary>
        /// 是否显示右侧console
        /// </summary>
        private bool _showConsoleGUI = false;

        private List<ConsoleMessage> entries = new List<ConsoleMessage>();
        Vector2 scrollPos;
        bool scrollToBottom = true; //新数据自定滚动到底部
        bool collapse;
        bool mTouching = false;

        const int margin = 20;
        Rect windowRect = new Rect(margin + Screen.width * 0.5f, margin, Screen.width * 0.5f - (2 * margin), Screen.height - (2 * margin));

        GUIContent clearLabel = new GUIContent("Clear", "Clear the contents of the console.");
        GUIContent collapseLabel = new GUIContent("Collapse", "Hide repeated messages.");
        GUIContent scrollToBottomLabel = new GUIContent("ScrollToBottom", "Scroll bar always at bottom");
        /// <summary>
        /// log工具类的Label字体样式
        /// </summary>
        GUIStyle LogLabelStyle = new GUIStyle();

        void Awake()
        {
            //Application.logMessageReceived += MainHandleLog;
            Application.logMessageReceivedThreaded += ThreadHandleLog;
            //定义OnGUi字体的样式
            LogLabelStyle.normal.background = null;
            LogLabelStyle.normal.textColor = Color.black;
            LogLabelStyle.fontSize = 30;//字体大小
            LogLabelStyle.wordWrap = true;
        }

        public void Init()
        {
            Debuger.Log("MGConsole init success");
        }

        void OnDestroy()
        {
            //Application.logMessageReceived -= MainHandleLog;
            Application.logMessageReceived -= ThreadHandleLog;
        }

        /// <summary>
        /// 打开或隐藏console
        /// </summary>
        public void ShowOrHideConsole()
        {
            this._showConsoleGUI = !this._showConsoleGUI;
        }


        void Update()
        {
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX
            //显示或隐藏
            if (Input.GetKeyDown(KeyCode.F1))
            {
                this._showConsoleGUI = !this._showConsoleGUI;
                Debuger.Log("this._showConsoleGUI：" + _showConsoleGUI);
            }
#elif UNITY_ANDROID
            if (Input.GetKeyUp(KeyCode.Escape))
            {
                _showConsoleGUI = !_showConsoleGUI;
            }
#elif UNITY_IOS
            if (!mTouching && Input.touchCount == 5)
            {
                mTouching = true;
                _showConsoleGUI = !_showConsoleGUI;
            } else if (Input.touchCount == 0){
                mTouching = false;
            }
#endif
        }

        void OnGUI()
        {
            try
            {
                //显示console面板
                if (this._showConsoleGUI)
                {
                    windowRect = GUILayout.Window(123456, windowRect, ConsoleWindow, "Console");
                }

            }
            catch (Exception e)
            {
                return;
            }
        }

        /// <summary>
        /// A window displaying the logged messages.
        /// </summary>
        void ConsoleWindow(int windowID)
        {
            if (scrollToBottom)
            {
                GUILayout.BeginScrollView(Vector2.up * entries.Count * 100.0f);
            }
            else
            {
                scrollPos = GUILayout.BeginScrollView(scrollPos);
            }
            // Go through each logged entry
            for (int i = 0; i < entries.Count; i++)
            {
                ConsoleMessage entry = entries[i];
                // If this message is the same as the last one and the collapse feature is chosen, skip it
                if (collapse && i > 0 && entry.Message == entries[i - 1].Message)
                {
                    continue;
                }
                // Change the text colour according to the log type
                switch (entry.Type)
                {
                    case LogType.Error:
                    case LogType.Exception:
                        GUI.contentColor = Color.red;
                        LogLabelStyle.normal.textColor = Color.red;
                        break;
                    case LogType.Warning:
                        GUI.contentColor = Color.yellow;
                        LogLabelStyle.normal.textColor = Color.yellow;
                        break;
                    default:
                        GUI.contentColor = Color.white;
                        LogLabelStyle.normal.textColor = Color.white;
                        break;
                }
                try
                {
                    if (entry.Type == LogType.Exception)
                    {
                        GUILayout.Label(string.Format("{0}||{1}", entry.Message, entry.StackTrace), LogLabelStyle);
                    }
                    else
                    {
                        GUILayout.Label(string.Format("{0}", entry.Message), LogLabelStyle);
                    }
                }
                catch (Exception e)
                {
                   return;
                }
                
            }
            GUI.contentColor = Color.white;
            GUILayout.EndScrollView();

            GUILayout.BeginHorizontal();
            // Clear button
            if (GUILayout.Button(clearLabel))
            {
                entries.Clear();
            }
            // Collapse toggle
            collapse = GUILayout.Toggle(collapse, collapseLabel, GUILayout.ExpandWidth(false));
            scrollToBottom = GUILayout.Toggle(scrollToBottom, scrollToBottomLabel, GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();
            // Set the window to be draggable by the top title bar
            GUI.DragWindow(new Rect(0, 0, 10000, 40));
        }

        void MainHandleLog(string message, string stackTrace, LogType type)
        {
            lock (entries)
            {
                ConsoleMessage entry = new ConsoleMessage(message, stackTrace, type, LogThread.Main);
                entries.Add(entry);
            }
            
        }

        void ThreadHandleLog(string message, string stackTrace, LogType type)
        {
            lock (entries)
            {
                ConsoleMessage entry = new ConsoleMessage(message, stackTrace, type, LogThread.Other);
                entries.Add(entry);
            }
           
        }

    }
}